package com.koron.ticket.work.workticket.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.koron.bean.base.Response;
import com.koron.bean.system.role.AppOrgJurisdictionBean;
import com.koron.bean.system.role.UserOwnJurisdictionBean;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.bean.workflow.SubmitterParam;
import com.koron.bean.workflow.WorkflowUser;
import com.koron.common.core.business.workflow.util.TextUtil;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.FastJsonUtils;
import com.koron.ticket.work.enums.TicketStatus;
import com.koron.ticket.work.enums.TicketType;
import com.koron.ticket.work.workPermit.bean.WorkPermit;
import com.koron.ticket.work.workPermit.mapper.WorkPermitMapper;
import com.koron.ticket.work.workend.bean.WorkEnd;
import com.koron.ticket.work.workend.mapper.WorkEndMapper;
import com.koron.ticket.work.workflow.bean.WorkFlow;
import com.koron.ticket.work.workflow.mapper.WorkFlowMapper;
import com.koron.ticket.work.worklocation.bean.WorkLocationBean;
import com.koron.ticket.work.workteam.bean.WorkTeam;
import com.koron.ticket.work.workticket.bean.CheckTimeOutDto;
import com.koron.ticket.work.workticket.bean.WorkTicket;
import com.koron.ticket.work.workticket.bean.WorkTicketQuery;
import com.koron.ticket.work.workticket.mapper.WorkTicketMapper;
import com.koron.ticket.work.workticket.service.WorkTicketService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("work/workticket")
@Api(tags = "两票管理-工作票")
public class WorkTicketController {

    private String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    private EamUser getEamUser() {
        return ThreadLocalContext.get();
    }

    @Autowired
    private WorkTicketService workTicketService;

    /**
     * 根据工作票类型，新增工作票
     *
     * @param type
     * @return Response
     * @version 1.0
     * @see Response
     */
    @GetMapping("addWorkTicket")
    @ApiOperation("新增工作票")
    public Response addWorkTicket(@RequestParam("type") String type) {
        return ADOConnection.runTask(getCurrDs(), workTicketService, "addWorkTicket", Response.class, type);
    }

    /**
     * 分页查询
     *
     * @param queryBean
     * @return Response
     * @version 1.0
     * @see Response
     */
    @PostMapping("/getListAndPaging")
    @ApiOperation("分页查询")
    public Response getListAndPaging(@RequestBody WorkTicketQuery queryBean) {
        PageHelper.startPage(queryBean.getPage(), queryBean.getPageSize(), queryBean.getOrderBy());
        ArrayList<String> units = CollUtil.newArrayList(getEamUser().getDeptId());
        List<AppOrgJurisdictionBean> appOrgJurisdictionBeans = Optional.ofNullable(getEamUser())
                .map(EamUser::getUserOwnJurisdictionBean)
                .map(UserOwnJurisdictionBean::getAppOrgJurisdictionBeanList).orElse(new ArrayList<>());
        Optional<AppOrgJurisdictionBean> firstopt = appOrgJurisdictionBeans.stream().filter(j -> getEamUser().getAppId().equals(j.getAppId())).findFirst();
        if (firstopt.isPresent()) {
            units.addAll(firstopt.get().getOrgStrList());
        }
        queryBean.setUnits(units);
        return ADOConnection.runTask(getCurrDs(), workTicketService, "getListAndPaging", Response.class, queryBean);
    }

    @GetMapping("/getListForChangeShifts")
    @ApiOperation("根据计划开始时间和工作负责人返回对应的数据")
    public Response<List<WorkTicket>> getListForChangeShifts(WorkTicketQuery workTicketQuery) {
        if (getCurrDs().equals("_default")) {
            return Response.ok(new ArrayList<>());
        }
        ArrayList<WorkTicket> list = ADOConnection.runTask(getCurrDs(), workTicketService, "getListForChangeShifts", ArrayList.class, workTicketQuery);
        return Response.ok(list);
    }

    @GetMapping("historyImport")
    @ApiOperation("历史导入")
    public Response historyImport(@RequestParam("id") String id) {
        return ADOConnection.runTask(getCurrDs(), workTicketService, "historyImport", Response.class, id);
    }

    @GetMapping("getByIdAndType")
    @ApiOperation("根据id和工作票类型查询单条工作票的相关数据")
    public Response getByIdAndType(@RequestParam("id") String id, @RequestParam("type") String type) {
        return ADOConnection.runTask(getCurrDs(), workTicketService, "getByIdAndType", Response.class, id, type);
    }

//    @GetMapping("getByIdAndTypeToChanage")
//    @ApiOperation("根据id、类型 查询相关变更信息 ")
//    public Response getByIdAndTypeToChanage(@RequestParam("id") String id, @RequestParam("type") String type) {
//        return ADOConnection.runTask(getCurrDs(),workTicketService,"getByIdAndType", Response.class, id, type);
//    }

    @GetMapping("getById")
    @ApiOperation("根据id和工作票类型查询单条工作票的相关数据")
    public Response getById(@RequestParam("id") String id) {
        return ADOConnection.runTask(getCurrDs(), workTicketService, "getById", Response.class, id);
    }

    @GetMapping("deleteByIdAndType")
    @ApiOperation("根据id和工作票类型删除单条工作票的数据")
    public Response deleteByIdAndType(@RequestParam("id") String id, @RequestParam("type") String type, @RequestParam @DateTimeFormat Date updateTime) {
        return ADOConnection.runTask(getCurrDs(), workTicketService, "deleteByIdAndType", Response.class, id, type, updateTime);
    }

    @GetMapping("electronicSignatureCallback")
    @ApiOperation("电子签章-签名回调接口")
    public Response electronicSignatureCallback(@RequestParam("workTicketId") String workTicketId, @RequestParam("tenantName") String tenantName,
                                                @RequestParam("signStatus") String signStatus) {
        return ADOConnection.runTask(getCurrDs(), workTicketService, "electronicSignatureCallback", Response.class, workTicketId, tenantName, signStatus);
    }

    @PostMapping("update")
    @ApiOperation("工作票更新")
    public Response update(@RequestBody WorkTicket workTicket) {
        return ADOConnection.runTask(getCurrDs(), workTicketService, "update", Response.class, workTicket);
    }

    @PostMapping("/queryTicketByOrderId")
    @ApiOperation("根据工单id获取工作票")
    public Response<List<WorkTicket>> queryTicketByOrderId(@RequestParam("orderId") String orderId) {

        Assert.isFalse(StrUtil.isEmpty(orderId), "工单id 不能为空");

        List<WorkTicket> list = ADOConnection.runTask(getCurrDs(), factory -> {
            WorkTicketMapper mapper = factory.getMapper(WorkTicketMapper.class);
            WorkFlowMapper workflowmapper = factory.getMapper(WorkFlowMapper.class);
            WorkEndMapper workendmapper = factory.getMapper(WorkEndMapper.class);
            WorkPermitMapper workpermitmapper = factory.getMapper(WorkPermitMapper.class);

            List<WorkTicket> workTickets = mapper.queryTicketByOrderId(orderId);
            List<String> workTicketIds = workTickets.stream().map(workTicket -> workTicket.getId()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(workTicketIds)) {
                List<WorkTeam> workTeams = mapper.queryWorkTeamByWorkTicketId(workTicketIds);
                List<WorkFlow> workFlows = workflowmapper.queryByWorkTicketIdIn(workTicketIds);
                List<WorkLocationBean> workLocations = mapper.queryWorkLocationBeanByWorkTicketId(workTicketIds);
                List<WorkEnd> workEnds = workendmapper.queryByWorkTicketIdInAndStatus(workTicketIds);
                List<WorkPermit> workPermits = workpermitmapper.queryByWorkTicketIdIn(workTicketIds);

                for (WorkTicket workTicket : workTickets) {
                    StringBuilder sb = new StringBuilder();
                    if (!CollectionUtils.isEmpty(workTeams)) {
                        for (WorkTeam workTeam : workTeams) {
                            if (workTicket.getId().equals(workTeam.getWorkTicketId())) {
                                if (workTeam.getWorkTeamName() != null) {
                                    sb.append(workTeam.getWorkTeamName());
                                    sb.append(",");
                                }
                            }
                        }
                        workTicket.setTeam(StrUtil.contains(sb.toString(),",") ? sb.toString().substring(0, sb.toString().lastIndexOf(",")) : "");
                    }
                    if (!CollectionUtils.isEmpty(workLocations)) {
                        sb = new StringBuilder();
                        for (WorkLocationBean workLocationBean : workLocations) {
                            if (workTicket.getId().equals(workLocationBean.getWorkTicketId())) {
                                if (workLocationBean.getLocationName() != null) {
                                    sb.append(workLocationBean.getLocationName());
                                    sb.append(",");
                                }
                            }
                        }
                        String sub = StrUtil.sub(sb.toString(), 0, sb.toString().lastIndexOf(","));
                        workTicket.setLocationName(sub);
                    }
                    // 工作终结时间
                    if (CollUtil.isNotEmpty(workEnds)) {
                        Date workEndDate = null;
                        // 工作一二三种、机械、线路二种工作票 工作票终终结时间
                        Predicate<WorkEnd> workEndPredicate1 = w -> w.getWorkTicketId().equals(workTicket.getId()) && w.getStatus().compareTo(TicketStatus.WORK_END.getStatus()) == 0;
                        // 过滤
                        Optional<WorkEnd> optworkend = workEnds.stream().filter(workEndPredicate1).findFirst();
                        workEndDate = optworkend.map(WorkEnd::getEndTime).orElse(null);

                        // 动火第二种
                        if (workTicket.getType().equals(TicketType.ThirdTicket.getWorkFlow())) {
                            // 动火第二种 工作终结时间
                            Predicate<WorkEnd> workEndPredicate2 = w -> w.getWorkTicketId().equals(workTicket.getId()) && w.getStatus().compareTo(TicketStatus.TICKET_END.getStatus()) == 0;
                            // 过滤
                            Optional<WorkEnd> first = workEnds.stream().filter(workEndPredicate2).findFirst();
                            workEndDate = first.map(WorkEnd::getEndTime).orElse(null);
                        }
                        workTicket.setOEndTime(workEndDate);
                    }
                    // 许可时间
                    if (CollUtil.isNotEmpty(workPermits)) {
                        Optional<WorkPermit> permitOpt1 = workPermits.stream().filter(f -> workTicket.getId().equals(f.getWorkTicketId())).findFirst();
                        Date permitDate = permitOpt1.map(WorkPermit::getWorkTime).orElse(null);

                        //线路第二种
                        if (workTicket.getType().equals(TicketType.PowerLineSecond.getWorkFlow())) {
                            Optional<WorkFlow> permitOpt2 = workFlows.stream().filter(f -> workTicket.getId().equals(f.getWorkTicketId())).findFirst();
                            Date accDate = permitOpt2.map(WorkFlow::getOperationTime).orElse(null);
                            permitDate = accDate;
                        }
                        workTicket.setOPermitTime(permitDate);
                    }
                }
            }
            return workTickets;
        }, List.class);
        return Response.ok(list);
    }

    @PostMapping("/queryTicketDeptWorkFlowPerson/submitter")
    @ApiOperation("获取本部门所有人")
    public Response<List<WorkflowUser>> queryTicketUnitWorkFlowPersonSubmitter(@RequestBody SubmitterParam submitterParam) {

        String currDs = ThreadLocalContext.get().getCurrDs();
        log.info("接收到的参数:" + FastJsonUtils.getBeanToJson(submitterParam));
        Map<String, String> infoMap = TextUtil.toMapFromString(submitterParam.getFormVariables());
        List<WorkflowUser> list = new ArrayList<>();
        list = ADOConnection.runTask(currDs, workTicketService, "getTicketApproverThisOrgNoPost", List.class, infoMap.get("id"));//只查询本单位
        return Response.ok(list);
    }

    @PostMapping("/queryTicketDeptWorkFlowPerson/handler")
    @ApiOperation("获取本部门所有人")
    public Response<List<WorkflowUser>> queryTicketUnitWorkFlowPersonHandler(@RequestBody SubmitterParam submitterParam) {
        return queryTicketUnitWorkFlowPersonSubmitter(submitterParam);
    }

    @PostMapping("/checkTimeOut")
    @ApiOperation("检查票据过期")
    public Response<List<WorkflowUser>> checkTimeOut(@RequestBody CheckTimeOutDto dto) {
        Assert.isFalse(StrUtil.isBlank(dto.getId()), "票据标识不能为空");
        ADOConnection.runTask(getCurrDs(), workTicketService, "checkTimeOutforeend", Response.class, dto.getId(), dto.getUpdateTime());
        return Response.ok();
    }


}
